﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Security.Principal;
using AuthenticationService.Client.Controls.Interfaces;

namespace AuthenticationService.Client.Controls
{
    [TemplatePart(Name="Core", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "LoginContainer", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "LoggedInContainer", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "LoginButton", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "LogoutButton", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "ProfileButton", Type = typeof(FrameworkElement))]
    [TemplateVisualState(Name = "LoggedIn", GroupName = "LoginStatusStates")]
    [TemplateVisualState(Name = "LoggedOut", GroupName = "LoginStatusStates")]
    public class LoginStatus : Control, ILoginCommandObject
    {
        private FrameworkElement corePart;
        private FrameworkElement loginContainerPart;
        private FrameworkElement loggedInContainerPart;
        private ButtonBase loginButtonPart;
        private ButtonBase logoutButtonPart;
        private ButtonBase profileButtonPart;
        public event RoutedEventHandler Login;
        public event RoutedEventHandler Logout;
        public event RoutedEventHandler ShowProfile;

        public static readonly DependencyProperty IsAuthenticatedProperty = DependencyProperty.Register("IsAuthenticated", typeof(bool), typeof(LoginStatus), new PropertyMetadata(LoginStatus.OnIsAuthenticatedChanged));
        private bool isAuthenticated;
        public bool IsAuthenticated
        {
            get
            {
                return isAuthenticated;
            }
            set
            {
                isAuthenticated = value;
                GoToState(true);
            }
        }
        private static void OnIsAuthenticatedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            LoginStatus control = d as LoginStatus;
            bool isAuth = false;
            try
            {
                isAuth = (bool)e.NewValue;
            }
            catch
            {
            }
            control.IsAuthenticated = isAuth;
        }

        private string username;
        public static readonly DependencyProperty UsernameProperty = DependencyProperty.Register("Username", typeof(string), typeof(LoginStatus), new PropertyMetadata(LoginStatus.OnUsernameChanged));
        public string Username
        {
            get
            {
                return username;
            }
            set
            {
                username = value;
                GoToState(true);
            }
        }
        private static void OnUsernameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            LoginStatus control = d as LoginStatus;
            string un = String.Empty;
            try
            {
                un = e.NewValue as string;
            }
            catch
            {
            }
            control.username = un;
        }

        public LoginStatus()
        {
            this.DefaultStyleKey = typeof(LoginStatus);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            CorePart = GetTemplateChild("Core") as FrameworkElement;
            LoginContainerPart = GetTemplateChild("LoginContainer") as FrameworkElement;
            LoggedInContainerPart = GetTemplateChild("LoggedInContainer") as FrameworkElement;
            LoginButtonPart = GetTemplateChild("LoginButton") as ButtonBase;
            LogoutButtonPart = GetTemplateChild("LogoutButton") as ButtonBase;
            ProfileButtonPart = GetTemplateChild("ProfileButton") as ButtonBase;
            GoToState(false);
        }

        private void GoToState(bool useTransitions)
        {
            if (isAuthenticated)
            {
                VisualStateManager.GoToState(this, "LoggedIn", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "LoggedOut", useTransitions);
            }
        }

        private FrameworkElement CorePart
        {
            get
            {
                return corePart;
            }
            set
            {
                FrameworkElement oldCorePart = corePart;

                //detach event handlers from existing part
                if (oldCorePart != null)
                {
                    
                }

                corePart = value;

                //attach event handlers to part
                if (corePart != null)
                {
                }
            }
        }

        private FrameworkElement LoginContainerPart
        {
            get
            {
                return loginContainerPart;
            }
            set
            {
                FrameworkElement oldLoginContainerPart = loginContainerPart;

                //detach event handlers from existing part
                if (oldLoginContainerPart != null)
                {

                }

                loginContainerPart = value;

                //attach event handlers to part
                if (loginContainerPart != null)
                {
                }
            }
        }

        private FrameworkElement LoggedInContainerPart
        {
            get
            {
                return loggedInContainerPart;
            }
            set
            {
                FrameworkElement oldLoggedInContainerPart = loggedInContainerPart;

                //detach event handlers from existing part
                if (oldLoggedInContainerPart != null)
                {

                }

                loggedInContainerPart = value;

                //attach event handlers to part
                if (loggedInContainerPart != null)
                {
                }
            }
        }

        private ButtonBase LoginButtonPart
        {
            get
            {
                return loginButtonPart;
            }
            set
            {
                ButtonBase oldLoginButtonPart = loginButtonPart;

                //detach event handlers from existing part
                if (oldLoginButtonPart != null)
                {
                    oldLoginButtonPart.Click -= new RoutedEventHandler(loginButtonPart_Click);
                }

                loginButtonPart = value;

                //attach event handlers to part
                if (loginButtonPart != null)
                {
                    loginButtonPart.Click += new RoutedEventHandler(loginButtonPart_Click);
                }
            }
        }

        private ButtonBase LogoutButtonPart
        {
            get
            {
                return logoutButtonPart;
            }
            set
            {
                ButtonBase oldLogoutButtonPart = logoutButtonPart;

                //detach event handlers from existing part
                if (oldLogoutButtonPart != null)
                {
                    oldLogoutButtonPart.Click -= new RoutedEventHandler(logoutButtonPart_Click);
                }

                logoutButtonPart = value;

                //attach event handlers to part
                if (logoutButtonPart != null)
                {
                    logoutButtonPart.Click += new RoutedEventHandler(logoutButtonPart_Click);
                }
            }
        }

        private ButtonBase ProfileButtonPart
        {
            get
            {
                return profileButtonPart;
            }
            set
            {
                ButtonBase oldProfileButtonPart = profileButtonPart;

                //detach event handlers from existing part
                if (oldProfileButtonPart != null)
                {
                    oldProfileButtonPart.Click -= new RoutedEventHandler(profileButtonPart_Click);
                }

                profileButtonPart = value;

                //attach event handlers to part
                if (profileButtonPart != null)
                {
                    profileButtonPart.Click += new RoutedEventHandler(profileButtonPart_Click);
                }
            }
        }

        void loginButtonPart_Click(object sender, RoutedEventArgs e)
        {
            if (Login != null)
            {
                Login(this, e);
            }
        }

        void logoutButtonPart_Click(object sender, RoutedEventArgs e)
        {
            if (Logout != null)
            {
                Logout(this, e);
            }
        }

        void profileButtonPart_Click(object sender, RoutedEventArgs e)
        {
            if (ShowProfile != null)
            {
                ShowProfile(this, e);
            }
        }
    }
}
